﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using Microsoft.SharePoint;

namespace SKN
{
    /// <summary>
    /// Contains common method for List
    /// </summary>
    public static class List
    {
        /// <summary>
        /// Use this method to create a new list/ document library
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="listType"></param>
        /// <example>List.CreateList(web,"Latest Updates","Announcements");</example>
        public static void CreateList(SPWeb web, string listname, string listType)
        {
            switch (listType.ToLower())
            {
                case "tasks":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.", SPListTemplateType.Tasks);
                    break;

                case "announcements":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.", SPListTemplateType.Announcements);
                    break;

                case "picturelibrary":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.",
                                  SPListTemplateType.PictureLibrary);
                    break;

                case "contacts":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.", SPListTemplateType.Contacts);
                    break;

                case "workflowhistory":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.",
                                  SPListTemplateType.WorkflowHistory);
                    break;

                case "links":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.", SPListTemplateType.Links);
                    break;

                case "documentlibrary":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.",
                                  SPListTemplateType.DocumentLibrary);
                    break;

                case "wiki":
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.",
                                  SPListTemplateType.WebPageLibrary);
                    break;

                default:
                    web.Lists.Add(listname, "This is " + listType.ToLower() + " list.", SPListTemplateType.GenericList);
                    break;
            }
        }

        /// <summary>
        /// Use this method to delete a list
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        public static void DeleteList(SPWeb web, string listname)
        {
            SPList list = web.Lists[listname];
            Guid listGuid = list.ID;
            if (!listGuid.Equals(Guid.Empty))
            {
                web.Lists.Delete(listGuid);
            }
        }

        /// <summary>
        /// Use this function to add a new view to a list/document library
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="viewname"></param>
        /// <param name="fieldNames"></param>
        public static void CreateView(SPWeb web, string listname, string viewname, IEnumerable<string> fieldNames)
        {
            const string defaultquery = "";

            var viewfields = new StringCollection();

            //Title field is always needed by SharePoint sites and it is always automatically created by WSS/MOSS even though you didn't tell it to
            foreach (string s in fieldNames)
            {
                viewfields.Add(s);
            }

            SPList list = web.Lists[listname];

            list.Views.Add(viewname, viewfields, defaultquery, 100, true, false);

            list.Update();
        }

        /// <summary>
        /// Use this function to delete a view from given list / document library
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="viewname"></param>
        public static void DeleteView(SPWeb web, string listname, string viewname)
        {
            SPList list = web.Lists[listname];

            foreach (SPView view in list.Views)
            {
                if (string.Equals(view.Title, viewname, StringComparison.InvariantCultureIgnoreCase))
                {
                    list.Views.Delete(view.ID);
                    break;
                }
            }

            list.Update();
        }

        /// <summary>
        /// Use this method to enable some advanced settings for list / document library
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">Name of the list</param>
        /// <param name="hidden"></param>
        /// <param name="hideFromSearch"></param>
        public static void EnableListAdvancedSettings1(SPWeb web, string listName, bool hidden, bool hideFromSearch)
        {
            SPList list = web.Lists[listName];
            list.Hidden = hidden;
            list.NoCrawl = hideFromSearch;
            list.Update();
        }

        /// <summary>
        /// Use this method to enable some advanced settings for list / document library
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="enableContentType"></param>
        /// <param name="enableVersioning"></param>
        /// <param name="enableMinorVersioning"></param>
        public static void EnableListAdvancedSettings2(SPWeb web, string listName, bool enableContentType,bool enableVersioning, bool enableMinorVersioning)
        {
            SPList list = web.Lists[listName];

            list.ContentTypesEnabled = enableContentType;
            list.EnableVersioning = enableVersioning;
            if (enableVersioning)
            {
                list.EnableMinorVersions = enableMinorVersioning;
            }


            list.Update();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="web"></param>
        public static void AddField(SPWeb web)
        {
            throw new NotImplementedException("If using from feature : Use element manifest file to add Field(s).");
        }

        /// <summary>
        /// Use this function to add a new drop down field
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="fieldName"></param>
        /// <param name="defaultValue"></param>
        public static void AddDropdownField(SPWeb web, string listName, string fieldName, string defaultValue)
        {
            SPList list = web.Lists[listName];

            // Set additional settings of the new field.    
            var fieldChoice = new SPFieldChoice(list.Fields, fieldName)
                                  {
                                      DefaultValue = defaultValue,
                                      EditFormat = SPChoiceFormatType.Dropdown
                                  };
            fieldChoice.Update();

            list.Update();
        }

        /// <summary>
        /// Use this method to add a new field with context menu document library. By default Name field only has the drop drop menu
        /// </summary>
        /// <param name="web"></param>
        /// <param name="doclibName"></param>
        /// <param name="newFieldName"></param>
        public static void AddNewFieldWithMenuInDocLib(SPWeb web, string doclibName, string newFieldName)
        {
            //var newFieldName = "Title";
            SPList list = web.Lists[doclibName];
            Guid fieldId = Guid.NewGuid();
            string fieldDef = @"<Field ID='" + (fieldId) +
                              @"' SourceID='http://schemas.microsoft.com/sharepoint/v3'   
                Name='" +
                              newFieldName + @"'  
                StaticName='" + newFieldName +
                              @"'  
                Group='Custom Fields'  
                ReadOnly='TRUE'  
                Type='Computed'  
                DisplayName='" +
                              newFieldName +
                              @"'  
                DisplayNameSrcField='FileLeafRef'  
                Filterable='FALSE'  
                ClassInfo='Menu'  
                AuthoringInfo='(with menu v1)'><!-- _locID@DisplayName='camlionet75' _locComment=' ' --><!-- _locID@AuthoringInfo='115' _locComment=' ' -->  
            <FieldRefs>  
                <FieldRef ID='{fa564e0f-0c70-4ab9-b863-0177e6ddd247}' Name='Title'/>  
                <FieldRef ID='{687c7f94-686a-42d3-9b67-2782eac4b4f8}' Name='FileLeafRef'/>  
                <FieldRef ID='{3c6303be-e21f-4366-80d7-d6d0a3b22c7a}' Name='_EditMenuTableStart'/>  
                <FieldRef ID='{2ea78cef-1bf9-4019-960a-02c41636cb47}' Name='_EditMenuTableEnd'/>  
                <FieldRef ID='{9d30f126-ba48-446b-b8f9-83745f322ebe}' Name='LinkFilenameNoMenu'/>  
                <FieldRef ID='{687c7f94-686a-42d3-9b67-2782eac4b4f8}' Name='FileLeafRef'/>  
                <FieldRef ID='{30bb605f-5bae-48fe-b4e3-1f81d9772af9}' Name='FSObjType'/>  
                <FieldRef ID='{998b5cff-4a35-47a7-92f3-3914aa6aa4a2}' Name='Created_x0020_Date'/>  
                <FieldRef ID='{94f89715-e097-4e8b-ba79-ea02aa8b7adb}' Name='FileRef'/>  
                <FieldRef ID='{39360f11-34cf-4356-9945-25c44e68dade}' Name='File_x0020_Type'/>  
                <FieldRef ID='{03e45e84-1992-4d42-9116-26f756012634}' Name='ContentTypeId'/>  
            </FieldRefs>  
            <DisplayPattern>  
                <FieldSwitch>   
                    <Expr><GetVar Name='FreeForm'/></Expr>  
                    <Case Value='TRUE'><Field Name='LinkFilenameNoMenu'/></Case>  
                    <Default>  
                        <Field Name='_EditMenuTableStart'/>          
                <IfEqual>  
                <Expr1><LookupColumn Name='FSObjType'/></Expr1>  
                <Expr2>1</Expr2>  
                <Then>  
                    <FieldSwitch><Expr><GetVar Name='RecursiveView'/></Expr>  
                    <Case Value='1'>  
                        <LookupColumn Name='FileLeafRef' HTMLEncode='TRUE'/>  
                    </Case>  
                    <Default>  
                        <SetVar Name='UnencodedFilterLink'>  
                            <SetVar Name='RootFolder'><HTML>/</HTML><LookupColumn Name='FileRef'/></SetVar>  
                            <SetVar Name='FolderCTID'>  
                                <FieldSwitch><Expr><ListProperty Select='EnableContentTypes'/></Expr>  
                                    <Case Value='1'><Column Name='ContentTypeId'/></Case>  
                                </FieldSwitch>  
                            </SetVar>  
                            <FilterLink Default='' Paged='FALSE'/>  
                        </SetVar>  
                            <HTML><![CDATA[<A onfocus='OnLink(this)'  HREF=']]></HTML>  
                            <GetVar Name='UnencodedFilterLink' HTMLEncode='TRUE'/>  
                            <HTML><![CDATA[' onclick='javascript:EnterFolder(']]></HTML>  
                            <ScriptQuote NotAddingQuote='TRUE'><GetVar Name='UnencodedFilterLink'/></ScriptQuote>  
                            <HTML><![CDATA[');javascript:return false;'>]]></HTML>  
                            <LookupColumn Name='FileLeafRef' HTMLEncode='TRUE'/>  
                            <HTML><![CDATA[</A>]]></HTML>  
                        </Default>  
                        </FieldSwitch>  
                    </Then>  
                    <Else>  
                        <HTML><![CDATA[<A onfocus='OnLink(this)' HREF=']]></HTML>  
                        <Field Name='EncodedAbsUrl'/>  
                        <HTML><![CDATA[' onclick='DispDocItemEx(this,']]></HTML>  
                        <ServerProperty Select='HtmlTransform'/>  
                        <HTML><![CDATA[',']]></HTML>  
                        <ServerProperty Select='HtmlTrAcceptType'><Column Name='File_x0020_Type'/></ServerProperty>  
                        <HTML><![CDATA[',']]></HTML>  
                        <ServerProperty Select='HtmlTrHandleUrl'><Column Name='File_x0020_Type'/></ServerProperty>  
                        <HTML><![CDATA[',']]></HTML>  
                        <ServerProperty Select='HtmlTrProgId'><Column Name='File_x0020_Type'/></ServerProperty>  
                        <HTML><![CDATA[')'>]]></HTML>  
                            <UrlBaseName HTMLEncode='TRUE'><LookupColumn Name='Title'/></UrlBaseName>  
                            <HTML><![CDATA[</A>]]></HTML>  
                        <IfNew Name='Created_x0020_Date'>  
                            <HTML><![CDATA[<IMG SRC='/_layouts/1033/images/new.gif' alt=']]></HTML>  
                            <HTML>$Resources:core,new_gif_alttext</HTML><HTML><![CDATA['>]]></HTML>  
                        </IfNew>  
                    </Else>  
                    </IfEqual>  
                           <Field Name='_EditMenuTableEnd'/>  
                    </Default>  
                    </FieldSwitch>  
                </DisplayPattern>  
            </Field>";

            list.Fields.AddFieldAsXml(fieldDef, true, SPAddFieldOptions.AddToAllContentTypes);
            list.Update();
        }

        /// <summary>
        /// Use this to add new Content Type based on existing content type
        /// </summary>
        /// <param name="web"></param>
        /// <param name="parentContentTypeName"></param>
        /// <param name="newContentTypeName"></param>
        /// <param name="fieldLinks"></param>
        public static void AddContentType(SPWeb web, string parentContentTypeName, string newContentTypeName,IEnumerable<string> fieldLinks)
        {
            SPContentType baseType = web.AvailableContentTypes[parentContentTypeName];

            var newContentType = new SPContentType(baseType, web.ContentTypes, newContentTypeName);

            foreach (string fieldLink in fieldLinks)
            {
                newContentType.FieldLinks.Add(new SPFieldLink(web.AvailableFields[fieldLink]));
                web.ContentTypes.Add(newContentType);
            }

            web.Update();
        }

        /// <summary>
        /// Use this method to add an exisiting content type to list/document library
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="contentTypeName"></param>
        public static void AddContentTypeToList(SPWeb web, string listName, string contentTypeName)
        {
            SPList list = web.Lists[listName];
            SPContentType contentType = web.AvailableContentTypes[contentTypeName];
            list.ContentTypesEnabled = true;
            list.ContentTypes.Add(contentType);
            list.Update();
            web.Update();
        }

        /// <summary>
        /// Use this method to add fields to a view
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName">List / Library UI name</param>
        /// <param name="viewName"></param>
        /// <param name="fields"></param>
        public static void AddFieldsToView(SPWeb web, string listName, string viewName, IEnumerable<string> fields)
        {
            SPList list = web.Lists[listName];
            SPView view ;
            if(string.IsNullOrEmpty(viewName))
            {
             view = list.DefaultView;
            }
            else
            {
                 view = list.Views[viewName];
            }

            using (SPWeb rootWeb = web.Site.RootWeb)
            {
                foreach (string fieldLink in fields)
                {
                    view.ViewFields.Add(new SPField(rootWeb.AvailableFields, fieldLink));
                    view.Update();
                }
            }

            web.Update();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listName"></param>
        /// <param name="camlQuery"></param>
        public static void DeleteListItems (SPWeb web, string listName, string camlQuery)
        {
            throw new Exception("Look into CAML class for both delete methods");
        }

        /// <summary>
        /// Use this method to determine the Field Type
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        /// <example>FieldTypeFromText("Lookup");</example>
        public static SPFieldType FieldTypeFromText (string text)
        {
            SPFieldType ft = (SPFieldType)Enum.Parse(typeof(SPFieldType), text, true);
            return ft;
        }
    }
}